WebCodecs AudioDataã®åãæŽ»çšããŠãé«åºŠãªçã®ãªãŒãã£ãªåŠçãæäœããªã¢ã«ã¿ã€ã ãšãã§ã¯ããå®çŸããŸããåœéçãªéçºè åãã®å æ¬çãªã¬ã€ãã
WebCodecs AudioData: ã°ããŒãã«éçºè åããçã®ãªãŒãã£ãªåŠçãšæäœããã¹ã¿ãŒãã
ãŠã§ããã«ãã¡ãã£ã¢ã®æ¥éãªé²åã«ãããŠããã©ãŠã¶å ã§çã®ãªãŒãã£ãªããŒã¿ã«çŽæ¥ã¢ã¯ã»ã¹ããŠæäœããèœåã¯ããŸããŸãéèŠã«ãªã£ãŠããŸãããããŸã§ãéçºè ã¯é«åºŠãªãªãŒãã£ãªåŠçã®ããã«Web Audio APIã«äŸåããŠããŸããããããã¯åŒ·åã§ããäžæ¹ã§ãå€ãã®å Žåãåºç€ãšãªãçã®ããŒã¿ãæœè±¡åããŠããŸãããWebCodecs APIãç¹ã«ãã®AudioDataã€ã³ã¿ãŒãã§ãŒã¹ã®å°å ¥ã¯ã倧ããªè»¢æç¹ãšãªããéçºè ã¯åºæ¬çãªã¬ãã«ã§ãªãŒãã£ãªã¹ããªãŒã ã现ããå¶åŸ¡ã§ããããã«ãªããŸããããã®å æ¬çãªã¬ã€ãã¯ãçã®ãªãŒãã£ãªåŠçããªã¢ã«ã¿ã€ã æäœãããã³äžçäžã®é©æ°çãªãªãŒãã£ãªã¢ããªã±ãŒã·ã§ã³ã®ããã«AudioDataã®å¯èœæ§ã掻çšããããšããŠããåœéçãªéçºè audience ã察象ãšããŠããŸãã
çã®ãªãŒãã£ãªããŒã¿ã®éèŠæ§ã®çè§£
AudioDataã®è©³çްã«å ¥ãåã«ãçã®ãªãŒãã£ãªãžã®çŽæ¥ã¢ã¯ã»ã¹ããªãããã»ã©äŸ¡å€ãããã®ããçè§£ããããšãéèŠã§ããçã®ãªãŒãã£ãªããŒã¿ã¯ãé³ãäžé£ã®æ°å€ãµã³ãã«ãšããŠè¡šããŸããåãµã³ãã«ã¯ãç¹å®ã®æç¹ã«ããã鳿³¢ã®æ¯å¹ ïŒé³éïŒã«å¯Ÿå¿ããŸãããããã®ãµã³ãã«ãæäœããããšã§ãéçºè ã¯æ¬¡ã®ããšãå¯èœã«ãªããŸãã
- ã«ã¹ã¿ã ãªãŒãã£ãªãšãã§ã¯ãã®å®è£ : æšæºãã£ã«ã¿ãŒãè¶ ããŠããããã·ãããã°ã©ãã¥ã©ãŒã·ã³ã»ã·ã¹ããŸãã¯è€éãªç©ºéãªãŒãã£ãªã¬ã³ããªã³ã°ã®ãããªãŠããŒã¯ãªãšãã§ã¯ããäœæããŸãã
- é«åºŠãªãªãŒãã£ãªåæã®å®è¡: ããŒãæ€åºãé³å£°èªèããªããã»ãã·ã³ã°ããŸãã¯é³æ¥œæ å ±æ€çŽ¢ãªã©ã®ã¢ããªã±ãŒã·ã§ã³ã®ããã«ãåšæ³¢æ°ã³ã³ãã³ããé³éã¬ãã«ããŸãã¯éæž¡æ å ±ã®ãããªç¹åŸŽãæœåºããŸãã
- ãªãŒãã£ãªåŠçãã€ãã©ã€ã³ã®æé©å: ç¹ã«ãªã¢ã«ã¿ã€ã ã·ããªãªã«ãããŠãããã©ãŒãã³ã¹ãéèŠãªã¢ããªã±ãŒã·ã§ã³ã®ããã«ãã¡ã¢ãªç®¡çãšåŠçããžãã¯ããã现ããå¶åŸ¡ããŸãã
- ã¯ãã¹ãã©ãããã©ãŒã äºææ§ã®å®çŸ: ããŸããŸãªããã€ã¹ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã éã§ç°¡åã«å ±æããã³åŠçã§ãããæšæºåããããªãŒãã£ãªåœ¢åŒããã³ããŒã¿è¡šçŸãæ±ããŸãã
- 驿°çãªãªãŒãã£ãªã¢ããªã±ãŒã·ã§ã³ã®éçº: ã€ã³ã¿ã©ã¯ãã£ããªé³æ¥œäœéšãã¢ã¯ã»ã¹å¯èœãªã³ãã¥ãã±ãŒã·ã§ã³ããŒã«ããŸãã¯æ²¡å ¥åãªãŒãã£ãªç°å¢ãæ§ç¯ããŸãã
WebCodecs APIã¯ããŠã§ããã©ãããã©ãŒã ãžã®æ°ãã远å ã§ãããã¡ãã£ã¢ã³ãŒããã¯ããã³çã®ã¡ãã£ã¢ããŒã¿ãžã®ããäœã¬ãã«ã®ã¢ã¯ã»ã¹ãæäŸããããšã«ãããWeb Audio APIã®ãããªæ¢åã®APIãè£å®ããŸããããã«ããããªãŒãã£ãªããã³ãããªãã¬ãŒã ãšã®ããçŽæ¥çãªã€ã³ã¿ã©ã¯ã·ã§ã³ãå¯èœã«ãªãããŠã§ãããŒã¹ã®ãã«ãã¡ãã£ã¢ã¢ããªã±ãŒã·ã§ã³ã®æ°ããå¯èœæ§ãéãããŸãã
WebCodecs AudioDataã®ç޹ä»
WebCodecsã®AudioDataã€ã³ã¿ãŒãã§ãŒã¹ã¯ãçã®ãªãŒãã£ãªããŒã¿ã®ãã£ã³ã¯ã衚ããŸããããã¯ããªãŒãã£ãªãã¬ãŒã ãåŠçããã³è»¢éããããã®åºæ¬çãªæ§æèŠçŽ ãšããŠèšèšãããŠããŸããããé«ã¬ãã«ã®æœè±¡åãšã¯ç°ãªããAudioDataã¯éåžžããã¬ãŒã³åœ¢åŒã§ãªãŒãã£ãªãµã³ãã«ãžã®çŽæ¥ã¢ã¯ã»ã¹ãæäŸããŸãã
AudioDataã®äž»ãªç¹åŸŽ:
- ãµã³ãã«åœ¢åŒ: AudioDataã¯ããŸããŸãªåœ¢åŒã§ãªãŒãã£ãªã衚ãããšãã§ããŸãããäžè¬çã«ã¯ã€ã³ã¿ãŒãªãŒããŸãã¯ãã¬ãŒã³ã®32ãããæµ®åå°æ°ç¹ãµã³ãã«ïŒS32LEïŒãŸãã¯16ããã笊å·ä»ãæŽæ°ïŒS16LEïŒã§ããç¹å®ã®åœ¢åŒã¯ããœãŒã¹ãšäœ¿çšãããã³ãŒããã¯ã«ãã£ãŠç°ãªããŸãã
- ãã£ã³ãã«ã¬ã€ã¢ãŠã: ãªãŒãã£ãªãã£ã³ãã«ã®é çœ®æ¹æ³ãæå®ããŸãïŒäŸïŒã¢ãã©ã«ãã¹ãã¬ãªããµã©ãŠã³ããµãŠã³ãïŒã
- ãµã³ãã«ã¬ãŒã: 1ç§ãããã®ãµã³ãã«æ°ãæ£ç¢ºãªåçãšåŠçã«äžå¯æ¬ ã§ãã
- ã¿ã€ã ã¹ã¿ã³ã: ãªãŒãã£ãªãã£ã³ã¯ã®ãã¬ãŒã³ããŒã·ã§ã³æéã瀺ãã¿ã€ã ã¹ã¿ã³ãã
- æé: ãªãŒãã£ãªãã£ã³ã¯ã®æéã
AudioDataããªãŒãã£ãªã®ããã¯ã»ã«ããšèããŠãã ãããåã ã®ãã¯ã»ã«ãæäœããŠç»åãšãã§ã¯ããäœæã§ããã®ãšåãããã«ãåã ã®ãªãŒãã£ãªãµã³ãã«ãæäœããŠãµãŠã³ãã圢æããã³å€æã§ããŸãã
AudioDataã®ã³ã¢æäœ
AudioDataã®æäœã«ã¯ãããã€ãã®éèŠãªæäœãå«ãŸããŸãã
1. AudioDataã®ååŸ
AudioDataãåŠçããåã«ããããååŸããå¿ èŠããããŸããããã¯éåžžãããã€ãã®æ¹æ³ã§è¡ãããŸãã
- MediaStreamTrackãã:
getMutableChunks()ãŸãã¯getControllable()ã¡ãœããïŒå®éšçïŒã䜿çšããŠããªãŒãã£ãªMediaStreamTrackããAudioDataãååŸã§ããŸããããäžè¬çã§å®å®ããã¢ãããŒãã¯ãMediaStreamTrackProcessorã䜿çšããããšã§ãã - ãã³ãŒããŒãã: WebCodecs APIã®
AudioDecoderã䜿çšããŠãšã³ã³ãŒãããããªãŒãã£ãªïŒMP3ãAACãªã©ïŒããã³ãŒããããšããã³ãŒããŒã¯AudioDataãã£ã³ã¯ãåºåããŸãã - EncodedDataãã: AudioDataã¯rawããŒã¿ã§ãããæåã«ãšã³ã³ãŒããããããŒã¿ããéå§ããŠãã³ãŒãããå ŽåããããŸãã
MediaStreamTrackProcessorã䜿çšããŠãã€ã¯ãããªãŒãã£ãªãã£ã³ã¯ãååŸããäŸãèŠãŠã¿ãŸãããã
async function getAudioDataFromMicrophone() {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioTrack = stream.getAudioTracks()[0];
if (!audioTrack) {
console.error('No audio track found.');
return;
}
const processor = new MediaStreamTrackProcessor({ track: audioTrack });
const reader = processor.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// 'value' here is a VideoFrame or AudioData object.
// We are interested in AudioData.
if (value instanceof AudioData) {
console.log(`Received AudioData: Sample Rate=${value.sampleRate}, Channels=${value.numberOfChannels}, Duration=${value.duration}ms`);
// Process the AudioData here...
processRawAudioData(value);
value.close(); // Important to close the AudioData when done
} else {
value.close(); // Close if it's not AudioData
}
}
} catch (error) {
console.error('Error accessing microphone:', error);
}
}
function processRawAudioData(audioData) {
// This is where you'd implement your audio manipulation logic.
// For demonstration, we'll just log some info.
console.log(`Processing AudioData: ${audioData.format}, ${audioData.sampleRate}Hz, ${audioData.numberOfChannels} channels.`);
// Accessing raw sample data (this is a simplified conceptual example)
// The actual access might involve WebAssembly or specific APIs depending on the format.
// For planar floating-point data:
// const plane = audioData.getPlane(0); // Get the first channel's data
// const buffer = plane.buffer;
// const view = new Float32Array(buffer);
// console.log(`First sample of channel 0: ${view[0]}`);
}
// Call the function to start processing
// getAudioDataFromMicrophone();
泚: MediaStreamTrackProcessorãšãã®readableããããã£ã¯ãŸã å®éšçãªæ©èœã§ããç¹å®ã®ãã©ãŠã¶ãã©ã°ãæå¹ã«ããå¿
èŠãããå ŽåããããŸãã
2. Rawãµã³ãã«ããŒã¿ãžã®ã¢ã¯ã»ã¹
çã®ãªãŒãã£ãªåŠçã®äžæ žã¯ãå®éã®ãªãŒãã£ãªãµã³ãã«ã«ã¢ã¯ã»ã¹ããããšã«ãããŸããAudioDataã€ã³ã¿ãŒãã§ãŒã¹ã¯ãããã®ããã®ã¡ãœãããæäŸããŸãã
format: ãµã³ãã«åœ¢åŒã瀺ãæåå (äŸ: 'f32-planar', 's16-planar')ãnumberOfChannels: ãªãŒãã£ãªãã£ã³ãã«ã®æ°ãsampleRate: ãªãŒãã£ãªããŒã¿ã®ãµã³ãã«ã¬ãŒããnew AudioData({ format, sampleRate, numberOfChannels, timestamp, data }): æ°ããAudioDataãªããžã§ã¯ããäœæããããã®ã³ã³ã¹ãã©ã¯ã¿ãŒãallocationSize({ format, sampleRate, numberOfChannels, numberOfFrames }): æå®ãããAudioDataã«å¿ èŠãªã¡ã¢ãªãèšç®ããããã®éçã¡ãœãããcopyTo({ plane, format, sampleRate, numberOfChannels, /* ... */ }): ãªãŒãã£ãªããŒã¿ãæäŸãããArrayBufferã«ã³ããŒããŸããgetPlane(planeIndex): ç¹å®ã®ãã£ã³ãã«ïŒãã¬ãŒã³ïŒã®AudioData.Planeãªããžã§ã¯ããè¿ããŸãããã®ãã¬ãŒã³ã«ã¯bufferããããã£ããããŸãã
ãã€ããããã¡ãŒããã³åä»ãé
åïŒFloat32ArrayãInt16Arrayãªã©ïŒãçŽæ¥æäœããã®ãäžè¬çã§ãããµã³ãã«ããŒã¿ã®èªã¿åãæ¹æ³ãïŒæŠå¿µçã«ïŒèª¬æããŸãããã
function processAudioSamples(audioData) {
const format = audioData.format;
const sampleRate = audioData.sampleRate;
const channels = audioData.numberOfChannels;
console.log(`Processing format: ${format}, Sample Rate: ${sampleRate}, Channels: ${channels}`);
for (let i = 0; i < channels; i++) {
const plane = audioData.getPlane(i);
const buffer = plane.buffer;
if (format === 'f32-planar') {
const samples = new Float32Array(buffer);
console.log(`Channel ${i} has ${samples.length} samples.`);
// Manipulate 'samples' array here (e.g., amplify, add noise)
for (let j = 0; j < samples.length; j++) {
samples[j] = samples[j] * 1.2; // Amplify by 20%
}
// Important: After manipulation, you might need to copy it back or create a new AudioData.
} else if (format === 's16-planar') {
const samples = new Int16Array(buffer);
console.log(`Channel ${i} has ${samples.length} samples.`);
// Manipulate 'samples' array here
for (let j = 0; j < samples.length; j++) {
samples[j] = Math.max(-32768, Math.min(32767, samples[j] * 1.2)); // Amplify by 20%, clamp for s16
}
}
// Handle other formats as needed
}
}
3. ãªãŒãã£ãªããŒã¿ã®æäœ
ãµã³ãã«ãããã¡ãŒã«ã¢ã¯ã»ã¹ãããšãæäœã®å¯èœæ§ã¯åºå€§ã«ãªããŸããäžè¬çãªææ³ã次ã«ç€ºããŸãã
- ã²ã€ã³/é³éå¶åŸ¡: ãµã³ãã«å€ã«ã²ã€ã³ãã¡ã¯ã¿ãŒãæããŸãã
// Inside processAudioSamples loop, for Float32Array: samples[j] *= gainFactor; // gainFactor between 0.0 and 1.0 for reduction, > 1.0 for amplification - ããã·ã³ã°: 2ã€ã®ç°ãªã
AudioDataãªããžã§ã¯ããããµã³ãã«å€ãå ç®ããŸãïŒãµã³ãã«ã¬ãŒããšãã£ã³ãã«æ°ãäžèŽããŠããããšããŸãã¯ãªãµã³ãã«/ãªããã¯ã¹ããããšã確èªããŠãã ããïŒã// Assuming audioData1 and audioData2 are compatible: const mixedSamples = new Float32Array(samples1.length); for (let k = 0; k < samples1.length; k++) { mixedSamples[k] = (samples1[k] + samples2[k]) / 2; // Simple average mixing } - ãã§ãŒãã£ã³ã°: æéã®çµéãšãšãã«åŸã
ã«å¢å ãŸãã¯æžå°ããã²ã€ã³ãã¡ã¯ã¿ãŒãé©çšããŸãã
// Apply a fade-in to the first 1000 samples: const fadeInDuration = 1000; for (let j = 0; j < Math.min(samples.length, fadeInDuration); j++) { const fadeFactor = j / fadeInDuration; samples[j] *= fadeFactor; } - ãšãã§ã¯ãã®è¿œå : ãµã³ãã«ã·ãŒã±ã³ã¹ãæäœããŠãåºæ¬çãªããŒãã¹ãŸãã¯ãã€ãã¹ãã£ã«ã¿ãŒã®ãããªåçŽãªãã£ã«ã¿ãŒãå®è£
ããŸããããè€éãªãšãã§ã¯ãã§ã¯ãå€ãã®å Žåãè€æ°ã®ãµã³ãã«ãäžåºŠã«èæ
®ããã¢ã«ãŽãªãºã ãå¿
èŠã§ãã
// Example: Simple delay effect (conceptual, requires buffering previous samples) // let delayedSample = 0; // for (let j = 0; j < samples.length; j++) { // const currentSample = samples[j]; // samples[j] = (currentSample + delayedSample) / 2; // Mix current with delayed // delayedSample = currentSample; // Prepare for next iteration // }
4. æ°ããAudioDataã®äœæ
æäœåŸãå€ãã®å Žåããšã³ã³ãŒããŒãŸãã¯å¥ã®åŠç段éã«æž¡ãããã«ãæ°ããAudioDataãªããžã§ã¯ããäœæããå¿
èŠããããŸããã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã©ã¡ãŒã¿ãŒã«æ³šæããå¿
èŠããããŸãã
åŠçããããµã³ãã«ããæ°ããAudioDataãªããžã§ã¯ããäœæããäŸ:
function createAudioDataFromSamples(samplesArray, originalAudioData) {
const { sampleRate, numberOfChannels, format } = originalAudioData;
const frameCount = samplesArray.length / numberOfChannels; // Assuming interleaved for simplicity here, adjust for planar
const duration = (frameCount / sampleRate) * 1e6; // Duration in microseconds
const timestamp = originalAudioData.timestamp; // Or use a new timestamp
// For planar f32 format, you'd construct by planes.
// This example assumes you've processed and have data ready to be put into AudioData structure.
// Let's assume we process data into a single plane for simplicity in this example
// but real applications would handle multiple channels correctly.
const dataArrayBuffer = samplesArray.buffer;
// Determine the correct format for constructor based on processed data.
// If original was f32-planar, the new data should ideally be too.
// For demonstration, let's create a new f32-planar AudioData
// Creating a single-channel AudioData from Float32Array
const planeData = [{ buffer: dataArrayBuffer, stride: samplesArray.byteLength, offset: 0 }];
// The constructor needs careful handling of data and format.
// For 'f32-planar', the 'data' argument should be an array of planes, each with buffer, stride, offset.
const newAudioData = new AudioData({
format: 'f32-planar', // Match your processed data format
sampleRate: sampleRate,
numberOfChannels: 1, // Adjust based on your processed data
numberOfFrames: frameCount, // Number of samples per channel
timestamp: timestamp,
// The data argument depends on the format. For 'f32-planar', it's an array of planes.
// Here, assuming we have a single plane (channel).
data: planeData
});
return newAudioData;
}
5. ãšã³ã³ãŒãã£ã³ã°ãšåºå
æäœåŸãçã®AudioDataãåçãŸãã¯éä¿¡ã®ããã«æšæºåœ¢åŒïŒAACãOpusãªã©ïŒã«ãšã³ã³ãŒãããããšãå¿
èŠãªå ŽåããããŸããããã§AudioEncoderãç»å ŽããŸãã
async function encodeAndPlayAudio(processedAudioData) {
const encoder = new AudioEncoder({
output: chunk => {
// 'chunk' is an EncodedAudioChunk. Play it or send it.
console.log('Encoded chunk received:', chunk);
// For playback, you'd typically queue these chunks for decoding and playing.
// Or, if playing directly via AudioData, you'd add it to an AudioWorklet or similar.
},
error: error => {
console.error('AudioEncoder error:', error);
}
});
// Configure the encoder with the desired codec and parameters
const config = {
codec: 'opus',
sampleRate: processedAudioData.sampleRate,
numberOfChannels: processedAudioData.numberOfChannels,
bitrate: 128000 // Example bitrate
};
encoder.configure(config);
// Encode the processed AudioData
encoder.encode(processedAudioData);
// Flush the encoder to ensure all buffered data is processed
await encoder.flush();
encoder.close();
}
// Example usage:
// const manipulatedAudioData = ...; // Your processed AudioData object
// encodeAndPlayAudio(manipulatedAudioData);
é«åºŠãªãã¯ããã¯ãšã°ããŒãã«ãªèæ ®äºé
ã°ããŒãã«èŠæš¡ã§ãªãŒãã£ãªåŠçãè¡ãå Žåãèæ ®ãã¹ãããã€ãã®èŠçŽ ããããŸãã
1. ããã©ãŒãã³ã¹ã®æé©å
çã®ãªãŒãã£ãªãµã³ãã«ã®çŽæ¥æäœã¯ãèšç®è² è·ãé«ããªãå¯èœæ§ããããŸããããã©ãŒãã³ã¹ãéèŠãªã¢ããªã±ãŒã·ã§ã³ã®å Žå:
- WebAssembly (Wasm): è€éãªã¢ã«ãŽãªãºã ã«ã€ããŠã¯ãC/C++ã§å®è£ ããŠWebAssemblyã«ã³ã³ãã€ã«ããããšãæ€èšããŠãã ãããããã«ãããJavaScriptãšæ¯èŒããŠãæ°å€èšç®ã®ã¯ããã«é«éãªå®è¡ãå¯èœã«ãªããŸããAudioDataãããã¡ãŒãWasmã¢ãžã¥ãŒã«ã«æž¡ããåŠçãããããŒã¿ãåãåãããšãã§ããŸãã
- å¹ççãªããŒã¿åŠç: 倧éã®
ArrayBufferã®ã³ããŒãæå°éã«æããŸããcopyToãæ éã«äœ¿çšããå¯èœãªå Žåã¯ã€ã³ãã¬ãŒã¹ã§åä»ãé åãæäœããŸãã - ãããã¡ã€ãªã³ã°: ãã©ãŠã¶ã®éçºè ããŒã«ã䜿çšããŠãªãŒãã£ãªåŠçã³ãŒãããããã¡ã€ã«ããããã«ããã¯ãç¹å®ããŸãã
2. ã¯ãã¹ãã©ãŠã¶ããã³ã¯ãã¹ãã©ãããã©ãŒã ã®äºææ§
WebCodecsã¯Webæšæºã§ãããå®è£ ã®è©³çŽ°ãšæ©èœã®ãµããŒãã¯ããã©ãŠã¶ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠç°ãªãå ŽåããããŸãã
- æ©èœæ€åº: 䜿çšããåã«ãWebCodecsãšç¹å®ã®ã€ã³ã¿ãŒãã§ãŒã¹ã®å¯çšæ§ãåžžã«ç¢ºèªããŠãã ããã
- å®éšçãªæ©èœ: WebCodecsã®äžéšã®åŽé¢ã¯ãŸã å®éšçã§ããããã©ã°ãæå¹ã«ããå¿ èŠãããå Žåãããããšã«æ³šæããŠãã ãããã¿ãŒã²ãããã©ãããã©ãŒã ã§åŸ¹åºçã«ãã¹ãããŸãã
- ãªãŒãã£ãªåœ¢åŒ: éžæããã³ãŒããã¯ãšãµã³ãã«åœ¢åŒãåºããµããŒããããŠããããšã確èªããŸãã
3. ãªã¢ã«ã¿ã€ã åŠçãšã¬ã€ãã³ã·
ã©ã€ãã¹ããªãŒãã³ã°ãä»®æ³æ¥œåšããŸãã¯ã€ã³ã¿ã©ã¯ãã£ããªã³ãã¥ãã±ãŒã·ã§ã³ã®ãããªã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã¬ã€ãã³ã·ãæå°éã«æããããšãæãéèŠã§ãã
- AudioWorklet: Web Audio APIã®
AudioWorkletã¯ããªãŒãã£ãªåŠçå°çšã®ã¹ã¬ãããæäŸããåŸæ¥ã®ScriptProcessorNodeãããäœãã¬ã€ãã³ã·ãšããæ±ºå®è«çãªåäœãæäŸããŸããWebCodecs AudioDataåŠçãAudioWorkletå ã§çµ±åããŠããªã¢ã«ã¿ã€ã ãšãã§ã¯ããå®çŸã§ããŸãã - ãããã¡ãªã³ã°æŠç¥: ãªãŒãã£ãªã®ãããããã°ãªããã®çºçãªãã«ããããã¯ãŒã¯ãžãã¿ãŒãŸãã¯åŠçã®é å»¶ãåŠçããããã®ã¹ããŒããããã¡ãªã³ã°ãå®è£ ããŸãã
- ãã¬ãŒã ãµã€ãº: AudioDataãã£ã³ã¯ã®ãµã€ãºïŒãã¬ãŒã æ°ïŒã¯ãã¬ã€ãã³ã·ã«åœ±é¿ããŸãããã£ã³ã¯ãå°ããã»ã©ã¬ã€ãã³ã·ã¯äœããªããŸãããåŠçã®ãªãŒããŒãããã倧ãããªãå¯èœæ§ããããŸããæé©ãªãã©ã³ã¹ãèŠã€ããããã«å®éšããŸãã
4. åœéåãšã¢ã¯ã»ã·ããªãã£
ã°ããŒãã«ãªãŒãã£ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå Žåã¯ã以äžãèæ ®ããŠãã ããã
- ããŒã«ãªãŒãŒã·ã§ã³: ãªãŒãã£ãªã³ã³ãããŒã«ã«é¢é£ãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹èŠçŽ ã¯ããŒã«ã©ã€ãºããå¿ èŠããããŸãã
- ãªãŒãã£ãªã¢ã¯ã»ã·ããªãã£: ããžã¥ã¢ã©ã€ã¶ãŒããã©ã³ã¹ã¯ãªãã·ã§ã³ãªã©ãèŽèŠé害ã®ãããŠãŒã¶ãŒåãã®ãªãã·ã§ã³ãæäŸããŸããã«ã¹ã¿ã ãªãŒãã£ãªãšãã§ã¯ãããæ¯æŽæè¡ãå©çšããŠãããŠãŒã¶ãŒã®çè§£ã劚ããªãããã«ããŠãã ããã
- æåçãã¥ã¢ã³ã¹: ãªãŒãã£ãªããŒã¿èªäœã¯æ®éçã§ãããç¹å®ã®ãµãŠã³ããŸãã¯ãšãã§ã¯ãã®èªèãšå¥œã¿ã¯æåçã«ç°ãªãå ŽåããããŸãã倿§ãªå°åã§ã®ãŠãŒã¶ãŒãã¹ããæçã§ãã
ãŠãŒã¹ã±ãŒã¹ãšå°æ¥ã®å¯èœæ§
çã®AudioDataãæäœããæ©èœã¯ã驿°çãªWebã¢ããªã±ãŒã·ã§ã³ãžã®æãéããŸãã
- ã©ã€ããªãŒãã£ãªãšãã§ã¯ããã§ãŒã³: ãã¥ãŒãžã·ã£ã³ããã³ãªãŒãã£ãªãšã³ãžãã¢åãã®è€éãªãªãŒãã£ãªãšãã§ã¯ãã©ãã¯ããã©ãŠã¶ã§çŽæ¥æ§ç¯ããŸãã
- ã«ã¹ã¿ã ãªãŒãã£ãªã·ã³ã»ãµã€ã¶ãŒ: 波圢ããã³ã·ã³ã»ã·ã¹ãã©ã¡ãŒã¿ãŒã现ããå¶åŸ¡ããŠããŠããŒã¯ãªãµãŠã³ãçæããŒã«ãäœæããŸãã
- é«åºŠãªãã€ã¹ãã§ã³ãžã£ãŒ: ã³ãã¥ãã±ãŒã·ã§ã³ãŸãã¯ãšã³ã¿ãŒãã€ã¡ã³ãã®ããã®é«åºŠãªãªã¢ã«ã¿ã€ã é³å£°å€æŽããŒã«ãéçºããŸãã
- ã€ã³ã¿ã©ã¯ãã£ããªãŒãã£ãªããžã¥ã¢ã©ã€ã¶ãŒ: çã®ãªãŒãã£ãªã³ã³ãã³ãã«æ£ç¢ºã«å¿çãããã€ãããã¯ãªããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ãäœæããŸãã
- ããŒãœãã©ã€ãºããããªãŒãã£ãªäœéš: ãŠãŒã¶ãŒã®å¥œã¿ãç°å¢ããŸãã¯çäœèªèšŒããŒã¿ã«åºã¥ããŠãªãŒãã£ãªåçã調æŽããŸãã
- WebããŒã¹ã®ããžã¿ã«ãªãŒãã£ãªã¯ãŒã¯ã¹ããŒã·ã§ã³ïŒDAWïŒïŒ ãã匷åã§æ©èœè±å¯ãªWebããŒã¹ã®é³æ¥œå¶äœãœãããŠã§ã¢ãéçºããŸãã
- ã¢ã¯ã»ã¹å¯èœãªã³ãã¥ãã±ãŒã·ã§ã³ããŒã«: WebäŒè°ãã©ãããã©ãŒã ã®ãã€ãºæå¶ããšã³ãŒãã£ã³ã»ã«ã®ãããªæ©èœã匷åããŸãã
WebCodecs APIãæçãããã©ãŠã¶ã®ãµããŒããæ¡å€§ããã«ã€ããŠãçŽæ¥ãªãŒãã£ãªããŒã¿æäœã掻çšããã¯ãªãšã€ãã£ããªã¢ããªã±ãŒã·ã§ã³ãççºçã«å¢å ããããšãäºæ³ãããŸãããµã³ãã«ã¬ãã«ã§ãªãŒãã£ãªãæäœããæ©èœã¯ãé«åºŠãªãªãŒãã£ãªåŠçãæ°äž»åããäžçäžã®Webéçºè ã®æå ã«ãããããŸãã
çµè«
WebCodecs APIãšãã®AudioDataã€ã³ã¿ãŒãã§ãŒã¹ã¯ãWebãªãŒãã£ãªéçºã®ããã®åŒ·åãªé²æ©ã衚ããŠããŸããçã®ãªãŒãã£ãªãµã³ãã«ãžã®ããŒã¬ãã«ã¢ã¯ã»ã¹ãæäŸããããšã«ãããéçºè ã¯åŸæ¥ã®å¶éããè§£æŸãããé«åºŠã«ã«ã¹ã¿ãã€ãºããããªãŒãã£ãªåŠçããªã¢ã«ã¿ã€ã ãšãã§ã¯ããããã³é©æ°çãªæ©èœãå®è£ ã§ããŸãããããã®ãã¯ããã¯ã¯ãããžã¿ã«ãªãŒãã£ãªã®ååã®ããæ·±ãçè§£ãšæ éãªå®è£ ãå¿ èŠãšããŸãããæè»æ§ãšã¯ãªãšã€ãã£ããªå¶åŸ¡ã®é¢ã§ã®ã¡ãªããã¯èšãç¥ããŸããã
äžçäžã®éçºè ã«ãšã£ãŠãWebCodecs AudioDataãæ¡çšããããšã¯ãWebãªãŒãã£ãªã®æ°ããããã³ãã£ã¢ãåãéãããšãæå³ããŸããæ¬¡äžä»£ã®é³æ¥œå¶äœããŒã«ãæ§ç¯ããå Žåã§ããã³ãã¥ãã±ãŒã·ã§ã³ãã©ãããã©ãŒã ã匷åããå Žåã§ããæ²¡å ¥åã®ã€ã³ã¿ã©ã¯ãã£ããªãšã¯ã¹ããªãšã³ã¹ãäœæããå Žåã§ããçã®ãªãŒãã£ãªåŠçããã¹ã¿ãŒããããšãWebãã«ãã¡ãã£ã¢ã€ãããŒã·ã§ã³ã®æåç·ã«ãšã©ãŸãããã®éµãšãªããŸããæ¢çŽ¢ãå®éšããããŠãŠã§ãäžã®ãµãŠã³ãã®æªæ¥ãåµé ãå§ããŠãã ããã